package com.javiercp.ayudaapp;

import java.util.ArrayList;

import com.javiercp.ayudaapp.contacts.ContactAccessor;
import com.javiercp.ayudaapp.contacts.ContactEmail;
import com.javiercp.ayudaapp.contacts.ContactInfo;
import com.javiercp.ayudaapp.contacts.ContactPhone;
import com.javiercp.ayudaapp.preferences.ContactsPreferenceDeflater;
import com.javiercp.ayudaapp.preferences.ContactsPreferenceInflater;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceManager;
import android.preference.Preference.OnPreferenceClickListener;
import android.text.method.DigitsKeyListener;
import android.util.Log;
import android.widget.EditText;

public class Preferences extends PreferenceActivity {

	private static final int PICK_CONTACT_PHONE = 1;
	private static final int PICK_CONTACT_EMAIL = 2;
	
	private static final int DELETE_CONTACT_PHONE = 3;
	private static final int DELETE_CONTACT_EMAIL = 4;

	private final ContactAccessor mContactAccessor = ContactAccessor.getInstance();
	
	private String mContactName;
	private CharSequence[] mDialogOptions;
	private boolean[] mDialogSelection;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
        
        Preference pref = findPreference(getString(R.string.PHONE_ADD_BUTTON_KEY));
        pref.setOnPreferenceClickListener(phoneAddClick);    
        
        pref = findPreference(getString(R.string.EMAIL_ADD_BUTTON_KEY));
        pref.setOnPreferenceClickListener(emailAddClick);    
        
        pref = findPreference(getString(R.string.PHONE_LIST_PREFERENCE_KEY));
        String xml = PreferenceManager.getDefaultSharedPreferences(this).getString(getString(R.string.PHONE_LIST_PREFERENCE_KEY), "");
        ContactsPreferenceInflater cf = ContactsPreferenceInflater.getInstance();
        cf.inflate(xml, (PreferenceCategory) pref);
        //I don't really like this here... think about moving
        setPrefsListeners((PreferenceCategory) pref);
        
        pref = findPreference(getString(R.string.EMAIL_LIST_PREFERENCE_KEY));       
        xml = PreferenceManager.getDefaultSharedPreferences(this).getString(getString(R.string.EMAIL_LIST_PREFERENCE_KEY), "");
        cf.inflate(xml, (PreferenceCategory) pref);   
        //I don't really like this here... think about moving
        setPrefsListeners((PreferenceCategory) pref);
        
        pref = findPreference(getText(R.string.PORT_PREF));
        EditText myEditText = (EditText)((EditTextPreference)pref).getEditText(); 
        myEditText.setKeyListener(DigitsKeyListener.getInstance(false,true));
        
        pref = findPreference(getText(R.string.SOCKETF_PREF));
        myEditText = (EditText)((EditTextPreference)pref).getEditText(); 
        myEditText.setKeyListener(DigitsKeyListener.getInstance(false,true));
    }
    
    private final OnPreferenceClickListener phoneAddClick = new OnPreferenceClickListener() {
		public boolean onPreferenceClick(Preference preference) {						       
			startActivityForResult(mContactAccessor.getPickContactIntent(), PICK_CONTACT_PHONE);
			       
			return true;
		}
    };
    
    private final OnPreferenceClickListener emailAddClick = new OnPreferenceClickListener() {
		public boolean onPreferenceClick(Preference preference) {		
			startActivityForResult(mContactAccessor.getPickContactIntent(), PICK_CONTACT_EMAIL);
		       
			return true;
		}
    };
        
    //@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if ((requestCode == PICK_CONTACT_PHONE || requestCode == PICK_CONTACT_EMAIL) && resultCode == RESULT_OK) {
        	loadContactInfo(data.getData(), requestCode);
        }		
    }

    private void loadContactInfo(Uri contactUri, final int requestCode) {
    	AsyncTask<Uri, Void, ContactInfo> task;
    	 	
    	task = new AsyncTask<Uri, Void, ContactInfo>() {
    		@Override
    		protected ContactInfo doInBackground(Uri... uris) {
    			return mContactAccessor.loadContact(getContentResolver(), uris[0]);
    		}

    		@Override
    		protected void onPostExecute(ContactInfo result) { 
    			mContactName = result.getDisplayName();
    			
    			if (requestCode == PICK_CONTACT_PHONE) {
    				loadContactPhones(result);
    			}
    			if (requestCode == PICK_CONTACT_EMAIL) {
    				loadContactEmails(result);
    			}
    		}
    	};
	        
        task.execute(contactUri);
    }
     
    private void loadContactPhones(ContactInfo result) {
    	AsyncTask<ContactInfo, Void, ArrayList<ContactPhone>> task;
    		 	
    	task = new AsyncTask<ContactInfo, Void, ArrayList<ContactPhone>>() {
			@Override
			protected ArrayList<ContactPhone> doInBackground(ContactInfo... params) {
				return mContactAccessor.getContactPhones(getContentResolver(), params[0]);
			}
			
    		@Override
    		protected void onPostExecute(ArrayList<ContactPhone> result) {          		  
    			mDialogOptions = new CharSequence[result.size()];
    			mDialogSelection =  new boolean[ mDialogOptions.length ];
    			
    			for (int i = 0; i < mDialogOptions.length; i++) {
    				mDialogOptions[i] = result.get(i).getValue();
    			}
    			
    			showDialog(PICK_CONTACT_PHONE);
    		}
    	};
	        
        task.execute(result);
    }
    
    private void loadContactEmails(ContactInfo result) {
    	AsyncTask<ContactInfo, Void, ArrayList<ContactEmail>> task;
    		 	
    	task = new AsyncTask<ContactInfo, Void, ArrayList<ContactEmail>>() {
			@Override
			protected ArrayList<ContactEmail> doInBackground(ContactInfo... params) {
				return mContactAccessor.getContactEmails(getContentResolver(), params[0]);
			}
			
    		@Override
    		protected void onPostExecute(ArrayList<ContactEmail> result) {          		  
    			mDialogOptions = new CharSequence[result.size()];
    			mDialogSelection =  new boolean[ mDialogOptions.length ];
    			
    			for (int i = 0; i < mDialogOptions.length; i++) {
    				mDialogOptions[i] = result.get(i).getValue();
    			}
    			
    			showDialog(PICK_CONTACT_EMAIL);
    		}
    	};
	        
        task.execute(result);
    }
    
    @Override
    protected Dialog onCreateDialog(int id, Bundle bundle) {
    	Dialog retValue;
    	
    	switch (id) {
    		case PICK_CONTACT_PHONE:
    			retValue = BuildSelectionDialog(getString(R.string.dlgPhoneTile), 
    					id, 
    					(PreferenceCategory) findPreference(getString(R.string.PHONE_LIST_PREFERENCE_KEY)));
    			break;
	    	case PICK_CONTACT_EMAIL:
	    		retValue = BuildSelectionDialog(getString(R.string.dlgEmailTile), 
	    				id, 
	    				(PreferenceCategory) findPreference(getString(R.string.EMAIL_LIST_PREFERENCE_KEY)));
	    		break;
	    	case DELETE_CONTACT_PHONE:
	    		retValue = BuildDeleteDialog(getString(R.string.dlgDeletePhoneTile),
	    				getString(R.string.dlgDeletePhoneText), 
	    				id, 
	    				bundle.getString("PREF_KEY"), 
	    				(PreferenceCategory) findPreference(getString(R.string.PHONE_LIST_PREFERENCE_KEY)));
	    		break;
	    	case DELETE_CONTACT_EMAIL:
	    		retValue = BuildDeleteDialog(getString(R.string.dlgDeleteEmailTile),
	    				getString(R.string.dlgDeleteEmailText), 
	    				id, 
	    				bundle.getString("PREF_KEY"),  
	    				(PreferenceCategory) findPreference(getString(R.string.EMAIL_LIST_PREFERENCE_KEY)));
	    		break;
	    	default:
	    		retValue = null;
	    		break;
    	}
    	
    	return retValue;
    }
    
    private Dialog BuildDeleteDialog(String title, String message, final int dialogId,  final String prefToDeleteKey, final PreferenceCategory categoryPref) {
    	AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	
		builder.setTitle(title);
		builder.setMessage(message);
		
		builder.setPositiveButton(R.string.dlgOkButton, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				deletePref(categoryPref, prefToDeleteKey);
				storePref(categoryPref);
			}
        });
		builder.setNegativeButton(R.string.dlgCancelButton,  null);	
		
		// I don't like this solution much, but as these dialogs are only for setup it'll have to do
		Dialog dialog = builder.create();	
	    dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
	            public void onDismiss(DialogInterface dialog) {
	                removeDialog(dialogId);
	            }
	    });
		
		return dialog;
    }
    
    private Dialog BuildSelectionDialog(String title, final int dialogId, final PreferenceCategory categoryPref) {
    	AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	
		builder.setTitle(title);
		builder.setMultiChoiceItems(mDialogOptions, mDialogSelection, new DialogInterface.OnMultiChoiceClickListener() {
            public void onClick(DialogInterface dialog, int whichButton, boolean isChecked) {
            	Log.i(MyConstants.LOGTAG, "Selected option.");
            }   
        });
		
		builder.setPositiveButton(R.string.dlgOkButton, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				boolean updated = false;
				
				for( int i = 0; i < mDialogOptions.length; i++ ){
					if (mDialogSelection[i]) {
						addNewPref(categoryPref, mDialogOptions[i].toString(),  mContactName);
						updated = true;
					}  						
				}
				
				if (updated) storePref(categoryPref);
			}
        });
		builder.setNegativeButton(R.string.dlgCancelButton, null);
			
		// I don't like this solution much, but as these dialogs are only for setup it'll have to do
		Dialog dialog = builder.create();	
	    dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
	            public void onDismiss(DialogInterface dialog) {
	                removeDialog(dialogId);
	            }
	    });
		
    	return dialog;
    }
        
    private final OnPreferenceClickListener preferenceClick = new OnPreferenceClickListener() {
		public boolean onPreferenceClick(Preference preference) {						       	
			if (isPhone(preference)) {
				Bundle bundle = new Bundle();
				bundle.putString("PREF_KEY", preference.getKey());
				
				showDialog(DELETE_CONTACT_PHONE, bundle);	
			}
			else if (isEmail(preference)) {
				Bundle bundle = new Bundle();
				bundle.putString("PREF_KEY", preference.getKey());
				
				showDialog(DELETE_CONTACT_EMAIL, bundle);		
			}
				
			return true;
		}
    };
    
    private boolean isPhone(Preference preference) {
    	PreferenceCategory pref = (PreferenceCategory) findPreference(getString(R.string.PHONE_LIST_PREFERENCE_KEY));
	
    	Preference foo = pref.findPreference(preference.getKey());
    	
    	if (foo!=null) {
    		return foo.equals(preference);
    	}
    	else {
    		return false;
    	}
    }
    
    
    private boolean isEmail(Preference preference) {
    	PreferenceCategory pref = (PreferenceCategory) findPreference(getString(R.string.EMAIL_LIST_PREFERENCE_KEY));
	
    	Preference foo = pref.findPreference(preference.getKey());
    	
    	if (foo!=null) {
    		return foo.equals(preference);
    	}
    	else {
    		return false;
    	}
    }
    
    private void setPrefsListeners(PreferenceCategory pref) {      
    	for (int i=0;i<pref.getPreferenceCount();i++) {
			Preference foo = pref.getPreference(i);
			
			foo.setOnPreferenceClickListener(preferenceClick);
		}
    }
    
    private void addNewPref(PreferenceCategory pref, String title, String summary) {
		Preference newPref = new Preference(this);
		newPref.setTitle(title);
		newPref.setSummary(summary);
		newPref.setKey("DYNAMIC_PREF" + pref.getPreferenceCount());
		newPref.setOnPreferenceClickListener(preferenceClick);

	    pref.addPreference(newPref);
    }
    
    private void storePref(PreferenceCategory pref) {
        ContactsPreferenceDeflater cf = ContactsPreferenceDeflater.getInstance();
        String st = cf.deflate((PreferenceCategory) pref);
        
        SharedPreferences spf = PreferenceManager.getDefaultSharedPreferences(this);
        Editor editor = spf.edit();
        editor.putString(pref.getKey(), st);
        editor.commit();
    }
    
    private void deletePref(PreferenceCategory pref, String key) {
    	Preference foo = pref.findPreference(key);
    	
    	if (foo != null) {
    		pref.removePreference(foo);
    	}
    }
      
}
